package com.roocon.design_pattern.chapter06_two_termination;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AppServer extends Thread{

  private final int port;

  private static final int DEFAULT_PORT = 12722;

  private volatile boolean start = true;

  private List<ClientHandler> clientHandlers = new ArrayList<>();

  private final ExecutorService executor = Executors.newFixedThreadPool(10);

  private ServerSocket serverSocket;

  public AppServer(int port) {
    this.port = port;
  }

  public AppServer() {
    this(DEFAULT_PORT);
  }

  @Override public void run() {
    try {
      serverSocket = new ServerSocket(port);
      while (start) {
        Socket mSocket = serverSocket.accept();
        ClientHandler client = new ClientHandler(mSocket);
        clientHandlers.add(client);
        executor.submit(client);
      }
    } catch (IOException e) {
      //e.printStackTrace();
    }finally {
      this.dispose();
    }
  }

  private void dispose() {
    clientHandlers.forEach(ClientHandler::stop);
    this.executor.shutdown();
  }

  public void shutdown() throws IOException {
    this.start = false;
    this.interrupt();
    serverSocket.close();
  }

  public static void main(String[] args) {

  }


}
